package com.yunhe.merchants.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.listener.UploadDataListener;
import com.yunhe.common.model.ResultObject;
import com.yunhe.common.model.authority.Organization;
import com.yunhe.common.model.mybatis.PageResult;
import com.yunhe.common.util.RedisClient;
import com.yunhe.common.util.StringUtil;
import com.yunhe.merchants.client.AuthorityClient;
import com.yunhe.merchants.constant.MyProjectConsts;
import com.yunhe.merchants.domain.DataPlanProject;
import com.yunhe.merchants.domain.DataProject;
import com.yunhe.merchants.model.DataPlanProjectCondition;
import com.yunhe.merchants.model.DataProjectUpload;
import com.yunhe.merchants.repository.IDataPlanProjectRepository;
import com.yunhe.merchants.service.IDataPlanProjectService;
import com.yunhe.merchants.service.IDataProjectService;
import com.yunhe.merchants.util.IdUtils;
import com.yunhe.merchants.util.MyHeaderUtil;
import com.yunhe.common.util.CollectionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName DataPlanProjectServiceImpl
 * @Description TODO
 * @Author HeTao
 * @Date 2021/5/10 15:31
 * @Version 1.0
 **/
@Service(value = "dataPlanProjectService")
public class DataPlanProjectServiceImpl implements IDataPlanProjectService {

    private static final Logger logger = LoggerFactory.getLogger(DataPlanProjectServiceImpl.class);

    @Autowired
    private IDataPlanProjectRepository dataPlanProjectDAO;

    @Autowired
    private RedisClient redisClient;

    @Autowired
    private MyHeaderUtil myHeaderUtil;

    @Autowired
    private AuthorityClient authorityClient;

    @Autowired
    private IDataProjectService dataProjectService;

    @Override
    public void deleteDataPlanProject(List<String> ids) throws ArgumentErrorException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("登录信息已失效,请重新登录");
        }
        if(CollectionUtil.isNotEmpty(ids)){
            for (String id : ids) {
                dataPlanProjectDAO.deleteDataPlanProjectByPrimaryKey(id,headerUser);
            }
        }
    }

    private List<DataPlanProject> getDataPlanProject(DataPlanProjectCondition dataPlanProjectCondition){
        List<DataPlanProject> dataPlanProjects = new ArrayList<>();
        if(StringUtil.isEmpty(dataPlanProjectCondition.getKeyWords())){
            dataPlanProjects  = dataPlanProjectDAO.findPlanProjectByConditionWithOutKeyWords(dataPlanProjectCondition);
        }else {
            //当关键字搜索不为空时，先查询手机号 在查询客户信息  在查询企业名称
            if(StringUtil.isPhoneNumber(dataPlanProjectCondition.getKeyWords())){
                dataPlanProjects  = dataPlanProjectDAO.findPlanProjectByConditionWithCustTel(dataPlanProjectCondition);
                if(CollectionUtil.isEmpty(dataPlanProjects)){
                    dataPlanProjects  = dataPlanProjectDAO.findPlanProjectByConditionWithCustName(dataPlanProjectCondition);
                    if(CollectionUtil.isEmpty(dataPlanProjects)){
                        dataPlanProjects  = dataPlanProjectDAO.findPlanProjectByConditionWithCompanyName(dataPlanProjectCondition);
                    }
                }
            }else {
                dataPlanProjects  = dataPlanProjectDAO.findPlanProjectByConditionWithCustName(dataPlanProjectCondition);
                if(CollectionUtil.isEmpty(dataPlanProjects)){
                    dataPlanProjects  = dataPlanProjectDAO.findPlanProjectByConditionWithCompanyName(dataPlanProjectCondition);
                }
            }
        }
        return dataPlanProjects;
    }

    @Override
    public PageResult findPlansByCondition(DataPlanProjectCondition dataPlanProjectCondition) throws ArgumentErrorException {
        PageResult result = null;
        Long userId = myHeaderUtil.getHeaderUser();
        if(userId == null){
            throw new ArgumentErrorException("登录信息已失效,请重新登录");
        }
        //查询当前登录人的组织以及子组织
        subOrg(userId,dataPlanProjectCondition);
        PageHelper.startPage(dataPlanProjectCondition.getPage(),dataPlanProjectCondition.getSize());
        List<DataPlanProject> dataPlanProjects = new ArrayList<>();
        //查询关键字
        dataPlanProjects = getDataPlanProject(dataPlanProjectCondition);
        PageInfo<DataPlanProject> pageInfo = new PageInfo<>(dataPlanProjects);
        result = new PageResult(dataPlanProjectCondition.getPage(),dataPlanProjectCondition.getSize(), (int) pageInfo.getTotal(),dataPlanProjects);
        return result;
    }

    /**
     * 查询组织
     * @param userId
     * @param dataPlanProjectCondition
     */
    private void subOrg(Long userId, DataPlanProjectCondition dataPlanProjectCondition) {
        String orgIdStr = redisClient.get("Org:" + userId);
        if(dataPlanProjectCondition.getResponsibleDept() != null){
            orgIdStr = dataPlanProjectCondition.getResponsibleDept()+"-"+orgIdStr.split("-")[1];
        }
        //获取当前登录人的组织
        if(!StringUtil.isEmpty(orgIdStr)){
            //查询当前组织以及子组织信息
            ResponseEntity<ResultObject> responseEntity = authorityClient.getSubOrg(orgIdStr);
            if(responseEntity != null){
                if(responseEntity.getStatusCode().is2xxSuccessful()){
                    Object results = responseEntity.getBody().getResults();
                    List<Organization> organizations = JSON.parseArray(JSON.toJSONString(results),Organization.class);
                    if (CollectionUtil.isNotEmpty(organizations)) {
                        List<Long> orgIds = organizations.stream().filter(organization -> organization.getId() != null)
                                .map(Organization::getId).collect(Collectors.toList());
                        dataPlanProjectCondition.setOrgIds(orgIds);
                    }
                }
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public DataPlanProject createPlan(DataPlanProject dataPlanProject) throws ArgumentErrorException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("登录信息已失效,请重新登录");
        }
        dataPlanProject.setId(IdUtils.getId());
        DataProject dataProject = new DataProject();
        BeanUtils.copyProperties(dataPlanProject,dataProject);
        dataPlanProject.setCreateTime(new Date());
        dataPlanProject.setUpdater(headerUser);
        dataPlanProject.setUpdateTime(new Date());
        dataPlanProject.setProjectStatus(MyProjectConsts.COMPANY_STATUS.ToBeAssigned.value());
        dataPlanProject.setKnockBackStatus(MyProjectConsts.BOOLEAN.No.value());
        dataPlanProjectDAO.createDataPlanProject(dataPlanProject);
        dataProject.setPlanId(dataPlanProject.getId());
        dataProject.setDataType(MyProjectConsts.DATA_TYPE.ManagerProjectPool.value());
        //并同步到经理项目池
        dataProjectService.createDataProject(dataProject);
        return dataPlanProject;
    }

    @Override
    public DataPlanProject getDataPlanPorjectById(String id) {
        return dataPlanProjectDAO.searchDataPlanProjectByPrimaryKey(id);
    }

    @Override
    public void uploadPlans(MultipartFile file) throws ArgumentErrorException, IOException {
        Long headerUser = myHeaderUtil.getHeaderUser();
        if(headerUser == null){
            throw new ArgumentErrorException("登录信息已失效,请重新登录");
        }
        String orgIdStr = redisClient.get("Org:" + headerUser);
        Long orgId = Long.parseLong(orgIdStr.split("-")[0]);
        EasyExcel.read(file.getInputStream(), DataProjectUpload.class,
                new UploadDataListener(this,file.getOriginalFilename(),headerUser,
                        orgId,MyProjectConsts.DATA_TYPE.plan.value())).sheet().doRead();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void upload(List<DataProjectUpload> dataProejctUploads, Long userId, Long orgId, String dataType) {
        //策划部数据
        List<DataPlanProject> dataPlanProjects = new ArrayList<>();
        //同步经理项目池数据
        List<DataProject> dataProjects = new ArrayList<>();
        //upload转Do
        convertUploadToDo(dataProejctUploads,dataPlanProjects,dataProjects,userId,orgId,dataType);
        //批量插入
        if(CollectionUtil.isNotEmpty(dataPlanProjects)){
            dataPlanProjectDAO.insertBatch(dataPlanProjects);
            if(CollectionUtil.isNotEmpty(dataProjects)){
                dataProjectService.batchCreate(dataProjects);
            }
        }
        logger.info("导入{}条数据进入数据库",dataPlanProjects.size());
    }

    private void convertUploadToDo(List<DataProjectUpload> dataProejctUploads, List<DataPlanProject> dataPlanProjects,List<DataProject> dataProjects, Long userId, Long orgId, String dataType) {
        if(CollectionUtil.isNotEmpty(dataProejctUploads)){
            List<DataPlanProject> collect = dataProejctUploads.stream().map(e -> {
                DataPlanProject dataPlanProject = new DataPlanProject();
                dataPlanProject.setId(IdUtils.getId());
                BeanUtils.copyProperties(e, dataPlanProject);
                dataPlanProject.setCreateTime(new Date());
                dataPlanProject.setProjectStatus(MyProjectConsts.COMPANY_STATUS.ToBeAssigned.value());
                dataPlanProject.setEntryDept(orgId);
                dataPlanProject.setEntryPerson(userId);
                dataPlanProject.setUpdater(userId);
                dataPlanProject.setUpdateTime(new Date());
                dataPlanProject.setKnockBackStatus(MyProjectConsts.BOOLEAN.No.value());
                DataProject dataProject = new DataProject();
                BeanUtils.copyProperties(dataPlanProject, dataProject);
                dataProject.setId(IdUtils.getId());
                dataProject.setPlanId(dataPlanProject.getId());
                dataProject.setDataType(MyProjectConsts.DATA_TYPE.ManagerProjectPool.value());
                dataProjects.add(dataProject);
                return dataPlanProject;
            }).collect(Collectors.toList());
            dataPlanProjects.addAll(collect);
        }
    }

    @Override
    public List<DataPlanProject> exportPlans(String ids, DataPlanProjectCondition dataPlanProjectCondition) throws ArgumentErrorException {
        if(!StringUtil.isEmpty(ids)){
            String[] split = ids.split(",");
            dataPlanProjectCondition.setIds(Arrays.asList(split));
        }
        Long userId = myHeaderUtil.getHeaderUser();
        if(userId == null){
            throw new ArgumentErrorException("登录信息已失效,请重新登录");
        }
        //查询当前登录人的组织以及子组织
        subOrg(userId,dataPlanProjectCondition);
        List<DataPlanProject> dataPlanProjects = getDataPlanProject(dataPlanProjectCondition);
        return dataPlanProjects;
    }

    @Override
    public void editPlans(String id, DataPlanProject dataPlanProject) {
        dataPlanProject.setId(id);
        dataPlanProject.setUpdateTime(new Date());
        dataPlanProjectDAO.updateDataPlanProjectByPrimaryKeySelective(dataPlanProject);
        //同时修改公共商机库的同条数据以及我的项目的同条数据
        dataProjectService.updateDataProjectByPlanId(dataPlanProject);
    }

    @Override
    public void updateDataPlanProject(List<String> ids, String companyStatus, Long deptId, Long salesman) throws ArgumentErrorException {
        Long updateUserId = myHeaderUtil.getHeaderUser();
        if(updateUserId == null){
            throw new ArgumentErrorException("登录信息已失效,请重新登录");
        }
        if(CollectionUtil.isNotEmpty(ids)){
            dataPlanProjectDAO.updateDataPlanProject(ids,companyStatus,deptId,salesman,new Date(),updateUserId);
        }
    }

    @Override
    public void updateKnockBackStatusById(String id) throws ArgumentErrorException {
        Long userId = myHeaderUtil.getHeaderUser();
        if(userId == null){
            throw new ArgumentErrorException("登录信息已失效,请重新登录");
        }
        DataPlanProject dataPlanProject = new DataPlanProject();
        dataPlanProject.setId(id);
        dataPlanProject.setKnockBackStatus(MyProjectConsts.BOOLEAN.Yes.value());
        dataPlanProject.setUpdateTime(new Date());
        dataPlanProject.setUpdater(userId);
        dataPlanProjectDAO.updateDataPlanProjectByPrimaryKeySelective(dataPlanProject);
    }
}
